package com.mengmeizi.util;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
 * @author Sodino E-mail:sodinoopen@hotmail.com
 * @version Time：2011-8-18 上午10:37:21
 */
public class FileUtil {

	public static boolean deleteFile(String path) {
		File file = new File(path);
		return deleteFile(file);
	}

	public static boolean deleteFile(File file) {
		return file.delete();
	}

	/** 将指定文件中的内容全部读取出来。适用于小文件。 */
	public static byte[] read(File file) {
		byte[] data = null;
		FileInputStream fis = null;
		ByteArrayOutputStream baos = null;
		int read = -1;
		try {
			baos = new ByteArrayOutputStream();
			fis = new FileInputStream(file);
			while ((read = fis.read()) != -1) {
				baos.write(read);
			}
			data = baos.toByteArray();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			data = null;
			e.printStackTrace();
		} finally {
			try {
				if (baos != null) {
					baos.close();
				}
				if (fis != null) {
					fis.close();
				}

			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return data;
	}

	/**
	 * 创建一个文件。<br/>
	 * 如果该文件的目录结构不存在，则创建该目录结构。<br/>
	 * 如果该文件路径已经指向一个文件夹，则删除该文件夹并再次创建文件。<br/>
	 * 
	 * @param filePath
	 * @param recreate
	 *            如果该路径已经存在文件，是否删除原来的文件再重新创建。
	 */
	public static File createFile(String filePath, boolean recreate) {
		File file = new File(filePath);
		try {
			if (file.exists() == false) {
				file.getParentFile().mkdirs();
				file.createNewFile();
			} else {
				if (file.isDirectory()) {
					// CMDUtil.rmdir(filePath);
					rmdir(file);
					file.createNewFile();
				} else if (recreate) {
					file.delete();
					file.createNewFile();
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return file;
	}

	/** 向指定的文件中写入数据。 */
	public static void write(File fileCodeVersion, String content) {
		if (content == null) {
			return;
		}
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(fileCodeVersion);
			fos.write(content.getBytes());
			fos.flush();
		} catch (FileNotFoundException fnfe) {
			fnfe.printStackTrace();
		} catch (IOException ie) {
			ie.printStackTrace();
		} finally {
			try {
				if (fos != null) {
					fos.close();
				}
			} catch (IOException ie) {
				ie.printStackTrace();
			}
		}
	}

	/**
	 * @param folderPath
	 *            新创建文件夹的地址。
	 * @param recreate
	 *            是否重新创建。
	 */
	public static File mkdir(String folderPath, boolean recreate) {
		File file = new File(folderPath);
		if (file.isFile()) {
			file.delete();
		}
		if (file.isDirectory() && recreate) {
			rmdir(file);
		}
		file.mkdirs();
		return file;
	}

	/** 删除指定的文件夹下所有的目录及文件并且删除该文件夹本身。 */
	public static void rmdir(File folder) {
		File[] files = folder.listFiles();
		File tmp = null;
		for (int i = 0; i < files.length; i++) {
			tmp = files[i];
			if (tmp.isDirectory()) {
				rmdir(tmp);
			} else {
				tmp.delete();
			}
		}
		folder.delete();
	}

	/**
	 * @param filePath
	 *            指定文件的绝对路径或相对路径。
	 */
	public static String getFileName(String filePath) {
		int idxSpe = filePath.lastIndexOf(File.separator), idxDot = filePath.lastIndexOf(".");
		if (idxDot >= 0) {
			if (idxSpe < idxDot) {
				String name = filePath.substring(idxSpe + 1, idxDot);
				return name;
			}
		} else {
			if (filePath.endsWith(File.separator) == false) {
				String name = filePath.substring(idxSpe + 1);
				return name;
			}
		}
		return null;
	}

	/**
	 * 返回文件的后缀名。
	 * 
	 * @return 如果传入的参数为null，则返回null；如果传入的参数没有后缀，则返回长度为零的字符串；其余正常返回后缀名。
	 */
	public static String getFileSuffix(String filePath) {
		String suffix = null;
		if (filePath != null) {
			int idx = filePath.lastIndexOf(".");
			if (idx != -1) {
				suffix = filePath.substring(idx + 1);
			} else {
				suffix = "";
			}
		}
		return suffix;
	}

	/**
	 * 返回文件名（不包含后缀名）。
	 */
	public static String getFilePrefix(String filePath) {
		String prefix = null;
		if (filePath != null) {
			int idx = filePath.lastIndexOf(".");
			if (idx != -1) {
				prefix = filePath.substring(0, idx);
			} else {
				prefix = filePath;
			}
		}
		return prefix;
	}

	/**
	 * @param zipFile
	 *            读取的ZipFile
	 * @param entryName
	 *            读取的JarFile的指定项
	 */
	public static byte[] read(ZipFile zipFile, String entryName) {
		InputStream inStream = null;
		ByteArrayOutputStream baos = null;
		byte[] data = null;
		Enumeration<? extends ZipEntry> enumeration = zipFile.entries();
		try {
			while (enumeration.hasMoreElements()) {
				ZipEntry entry = enumeration.nextElement();
				if (entryName.equals(entry.getName())) {
					baos = new ByteArrayOutputStream();
					inStream = zipFile.getInputStream(entry);
					int read = -1;
					while ((read = inStream.read()) != -1) {
						baos.write(read);
					}
					data = baos.toByteArray();
					break;
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (baos != null) {
					baos.close();
				}
				if (inStream != null) {
					inStream.close();
				}
			} catch (IOException ie) {
				ie.printStackTrace();
			}
		}
		return data;
	}

	/**
	 * 将指定文件由关键字替换成指定的内容。
	 * 
	 * @param fSrc
	 *            执行替换的源文件。
	 * @param fDes
	 *            替换成功后新文件的地址。如果该值为null，则直接覆盖fSrc。
	 * @param key
	 *            替换的关键字。该关键字仅能
	 * @param content
	 *            欲替换的内容。
	 */
	public static boolean changeContent(File fSrc, File fDes, String key, String content) {
		boolean result = false;
		File fTmp = null;
		FileOutputStream fos = null;
		FileInputStream fis = null;
		BufferedReader br = null;
		String line = null;
		try {
			fis = new FileInputStream(fSrc);
			fTmp = new File(fSrc.getAbsolutePath() + ".tmp");
			fos = new FileOutputStream(fTmp);
			br = new BufferedReader(new InputStreamReader(fis));
			while ((line = br.readLine()) != null) {
				if (line.contains(key)) {
					result = true;
					line = line.replace(key, content);
				}
				line = line + "\n";
				fos.write(line.getBytes());
				fos.flush();
			}
			fos.flush();
		} catch (IOException ie) {
			ie.printStackTrace();
		} finally {
			try {
				if (fos != null) {
					fos.close();
				}
				if (br != null) {
					br.close();
				}
				if (fis != null) {
					fis.close();
				}
			} catch (IOException ie) {
				ie.printStackTrace();
			}
		}
		if (result) {
			if (fDes == null) {
				fSrc.delete();
				fTmp.renameTo(fSrc);
			} else {
				copyFile(fTmp, fDes);
				fTmp.delete();
			}
		}
		return result;
	}

	public static void copyFile(File fSrc, File fDes) {
		FileInputStream fis = null;
		FileOutputStream fos = null;
		byte[] data = new byte[1024];
		int readLength = -1;
		try {
			fis = new FileInputStream(fSrc);
			fos = new FileOutputStream(fDes);
			while ((readLength = fis.read(data)) != -1) {
				fos.write(data, 0, readLength);
				fos.flush();
			}
			fos.flush();
		} catch (IOException ie) {
			ie.printStackTrace();
		} finally {
			try {
				if (fis != null) {
					fis.close();
				}
				if (fos != null) {
					fos.close();
				}
			} catch (IOException ie) {
				ie.printStackTrace();
			}
		}
	}
}